package ca.ubc.icapture.genapha.actions;

import ca.ubc.icapture.genapha.forms.MoveGeneSnpForm;
import ca.ubc.icapture.genapha.forms.SearchForm;
import icapture.SQLMgr;
import icapture.beans.DB.Gene;
import icapture.beans.DB.GeneSet;
import icapture.beans.DB.SNP;
import icapture.beans.DB.SnpSet;
import java.util.ArrayList;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;

public class MoveGeneSnp extends Action {

    final static String noResults = "noResults";
    final static String showAll = "Show All";
    private ArrayList<String> errors = new ArrayList<String>();

    @Override
    public ActionForward execute(ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {
        ActionForward forward = new ActionForward();
        MoveGeneSnpForm searchForm = (MoveGeneSnpForm) form;
        errors.clear();
        // Parse input parameters.
        // GOTCHA: Done here to maximize code re-use.

        String[] searchText = null;
        if (searchForm.getSearchText() != null && !searchForm.getSearchText().trim().isEmpty()) {
            searchText = searchForm.getSearchText().trim().split("\n");
        }

        String geneSetLookUp = searchForm.getGeneSet();
        String snpSetLookUp = searchForm.getSnpSet();

        switch (searchForm.getSearchSelect()) {
            case 1:
                // SNP search
                ArrayList<SNP> snps = searchSnp(searchText);
                if (!snps.isEmpty()) {
                    moveSNPs(snps, snpSetLookUp);
                    forward = mapping.findForward("snpList");
                } else {
                    forward = mapping.findForward(noResults);
                }
                break;
            case 2:
                // Gene search
                ArrayList<Gene> geneList = searchGene(searchText);
                if (!geneList.isEmpty()) {
                    moveGenes(geneList, geneSetLookUp);
                    forward = mapping.findForward("geneList");
                } else {
                    forward = mapping.findForward(noResults);
                }
                break;
            default:
                forward = mapping.findForward(noResults);
                break;
        }
        String tmpErrors = "";
        if (errors != null) {
            for (String itr : errors) {
                tmpErrors += itr+"<br/>";
            }
        ActionErrors acErrors = new ActionErrors();
        ActionMessage acm = new ActionMessage("moveSnp.error.cannotMove", tmpErrors);
        acErrors.add("move", acm);
        saveErrors(request, acErrors);
        forward = mapping.findForward("failure");
        }

        return forward;
    }

    private ArrayList<SNP> searchSnp(String[] searchText) {
        ArrayList<SNP> snps = new ArrayList<SNP>();
        // Get all SNPs whose rs numbers are like the searching ones.
        if (searchText != null) {
            for (int i = 0; i < searchText.length; i++) {
                String keyword = searchText[i];
                SNP tmpSnp = SQLMgr.getSNP(keyword);
                if (tmpSnp == null) {
                    errors.add(keyword + " could not be found.");
                    continue;
                }
                snps.add(tmpSnp);
            }
        }
        return snps;
    }

    private ArrayList<Gene> searchGene(String[] searchText) {
        ArrayList<Gene> genes = new ArrayList<Gene>();
        // Get all genes whose names are like the searching ones.
        if (searchText != null) {
            for (int i = 0; i < searchText.length; i++) {
                String keyword = searchText[i].trim().toUpperCase();
                Gene tempGene = SQLMgr.getGene(keyword);
                if (tempGene == null) {
                    try{
                        tempGene = SQLMgr.getGeneByEntrezID(Integer.parseInt(keyword));
                    }
                    catch (NumberFormatException e){
                        errors.add(keyword + " could not be found.");
                        continue;
                    }
                    if (tempGene == null) {
                        //Gene not found
                        errors.add(keyword + " could not be found.");
                        continue;
                    }
                }
                genes.add(tempGene);
            }
        }
        return genes;
    }

    private void moveSNPs(ArrayList<SNP> snps, String snpSetLookUp) {
        if (snpSetLookUp == null && snpSetLookUp.equals("")) {
            return;
        }
        SnpSet snpSet = SQLMgr.getSnpSet(snpSetLookUp);
        for (SNP itr : snps) {
            String badSnp = SQLMgr.insertSnpSetWithErrorArray(snpSet, itr);
            if (badSnp != null) {
                errors.add(badSnp);
            }
        }
    }

    private void moveGenes(ArrayList<Gene> gene, String geneSetLookUp) {
        if (geneSetLookUp == null && geneSetLookUp.equals("")) {
            return;
        }
        GeneSet geneSet = SQLMgr.getGeneSet(geneSetLookUp);
        for (Gene itr : gene) {
            String badGene = SQLMgr.insertGeneSetWithErrorArray(geneSet, itr);
            if (badGene != null) {
                errors.add(badGene);
            }
        }
    }
}
